Go 并发原语之条件变量 Cond | 您所在的位置:网站首页 › go go go › Go 并发原语之条件变量 Cond |
Go 并发系列是根据我对晁岳攀老师的《Go 并发编程实战课》的吸收和理解整理而成,如有偏差,欢迎指正~Cond 是什么? Cond 是 Go 标准库 sync 包提供的原语。 顾名思义,Cond 和某个条件相关。这个条件需要一组 goroutine 共同完成,当条件还没有达成的时候,后续的 goroutine 都会被阻塞。一旦条件达成,被阻塞的 goroutine 都会被唤醒。 这个条件的表现形式并不固定,可以是一个变量达到某个阈值,也可以某个对象的状态满足某个条件。总之只要这个条件能判断 true 或者 false 就行。 开发中,使用 Cond 的场景很少,绝大部分需要使用 Cond 的场景都可以使用 Channel 来实现,这才是更地道的 Go 的用法。 Cond 的基本用法初始化和前面的 Mutex、RWMutex、WaitGroup 直接声明匿名变量不一样,Cond 的初始化需要传入一个 Locker 接口的实例(通常传入 Mutex 和 RWMutex)。 c := sync.NewCond(&sync.Mutex{})Cond 关联的 Locker 实例可以通过 c.L 访问。 三个方法Cond 有三个方法:Signal、Broadcast 和 Wait。 这三个方法名是计算机科学中条件变量的通用方法名。比如,C 语言中对应的方法名是 pthread_cond_wait、pthread_cond_signal 和 pthread_cond_broadcast。 我们分别看一下这三个方法。 Signal: 调用者通过该方法唤醒一个正在等待此 Cond 的 goroutine。如果此时没有等待的 goroutine,则无须通知 waiter,如果等待队列中有一个或者多个等待者,则移出第一个 goroutine 并唤醒它。 Broadcast: 和上面的 Signal 方法类似,只是 Broadcast 会清空队列,唤醒全部的等待中的 goroutine。 调用 Signal 和 Broadcast 的时候,不要求调用者持有锁 c.L 。 Wait: 调用该方法的 goroutine 会被放到 Cond 的等待队列中并阻塞,直到被 Signal 或者 Broadcast 方法唤醒。 调用 Wait 方法的时候一定要持有锁 c.L 。 应用示例用田径比赛举例。比赛前,选手们需要和观众们互动,并进行热身运动,等准备就绪后,会向裁判示意。裁判等到全部运动员都准备好之后,才会打响发令枪。 假设有10个运动员,1个裁判,比赛过程可以描述如下: func main() { c := sync.NewCond(&sync.Mutex{}) var ready int for i := 0; i |
CopyRight 2018-2019 实验室设备网 版权所有 |